package org.jeecg.modules.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.manager.entity.*;
import org.jeecg.modules.manager.mapper.*;
import org.jeecg.modules.manager.service.IPurchaseOrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 采购订单表
 * @Author: jeecg-boot
 * @Date:   2021-11-19
 * @Version: V1.0
 */
@Service
public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements IPurchaseOrderService {

    @Autowired
    private GoodsTypeMapper goodsTypeMapper;

    @Autowired
    private CarMapper carMapper;

    @Autowired
    private RepositoryMapper repositoryMapper;

    @Autowired
    private PurchaseOrderMapper purchaseOrderMapper;

    @Autowired
    private OrderGroupMapper orderGroupMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private CarInfoMapper carInfoMapper;

    @Autowired
    private SparePartsMapper sparePartsMapper;

    @Autowired
    private SupplierMapper supplierMapper;

    @Override
    public int addOrEdit(OrderGroupPurVo orderGroup, LoginUser loginUser) {
        OrderGroup real = new OrderGroup();
        BeanUtils.copyProperties(orderGroup,real);
        try {
            //有id则修改
            if (StringUtils.isNotBlank(orderGroup.getId())) {
                real.setOrderName(spellName(orderGroup, loginUser));
                orderGroupMapper.updateById(real);
                orderGroup.getPurchaseOrderAddVos().forEach(vo -> {
                    PurchaseOrder purchaseOrder = new PurchaseOrder();
                    BeanUtils.copyProperties(vo,purchaseOrder);
                    //查找商品价格计算总价和单价
                    CarInfo carInfo = carInfoMapper.selectById(vo.getPuroGoodsId());
                    if (Objects.nonNull(carInfo)){
                        purchaseOrder.setPuroPrice(new BigDecimal(carInfo.getInfoPrice()));
                    }else {
                        SpareParts spareParts = sparePartsMapper.selectById(purchaseOrder.getPuroGoodsId());
                        purchaseOrder.setPuroPrice(new BigDecimal(spareParts.getSparePartsPrice()));
                    }
                    //算一下总价
                    purchaseOrder.setPuroTotal(purchaseOrder.getPuroPrice().multiply(new BigDecimal(purchaseOrder.getPuroCount())));
                    purchaseOrderMapper.updateById(purchaseOrder);
                });
            }else {
                real.setId(UUIDGenerator.generate());
                //拼个名字吧。。。
                real.setOrderName(spellName(orderGroup, loginUser));
                real.setOrderType(OrderType.PURCHASE);
                real.setCreatedTime(new Date());
                real.setCreatedBy(loginUser.getUsername());
                real.setDeleted(DeletedEnum.FALSE);
                orderGroupMapper.insert(real);
                orderGroup.getPurchaseOrderAddVos().forEach(vo -> {
                    PurchaseOrder purchaseOrder = new PurchaseOrder();
                    BeanUtils.copyProperties(vo,purchaseOrder);
                    //查找商品价格计算总价和单价
                    CarInfo carInfo = carInfoMapper.selectById(vo.getPuroGoodsId());
                    if (Objects.nonNull(carInfo)){
                        purchaseOrder.setPuroPrice(new BigDecimal(carInfo.getInfoPrice()));
                    }else {
                        SpareParts spareParts = sparePartsMapper.selectById(purchaseOrder.getPuroGoodsId());
                        purchaseOrder.setPuroPrice(new BigDecimal(spareParts.getSparePartsPrice()));
                    }
                    //算一下总价
                    purchaseOrder.setPuroTotal(purchaseOrder.getPuroPrice().multiply(new BigDecimal(purchaseOrder.getPuroCount())));

                    purchaseOrder.setPuroRepoId(orderGroup.getPuroRepoId());
                    purchaseOrder.setId(UUIDGenerator.generate());
                    purchaseOrder.setOrderGroupId(real.getId());
                    purchaseOrder.setPuroNumber(purchaseOrder.getId());
                    purchaseOrder.setPuroStatus(0);
                    purchaseOrder.setDeleted(DeletedEnum.FALSE);
                    purchaseOrder.setCreatedBy(loginUser.getUsername());
                    purchaseOrder.setCreatedTime(new Date());
                    purchaseOrderMapper.insert(purchaseOrder);
                });
            }
            return 1;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    private String spellName(OrderGroupPurVo orderGroup, LoginUser loginUser) {
        //将订单组内的采购订单保存到list中
        List<String> collect = orderGroup.getPurchaseOrderAddVos().stream()
                .map(PurchaseOrderAddVo::getPuroGoodsId).collect(Collectors.toList());
        //将采购订单内的汽车信息查出，并将汽车信息用顿号拼接
        List<CarInfo> carInfos = carInfoMapper.selectList(new QueryWrapper<CarInfo>().in("info_id", collect));
        //查出汽车表的汽车名来
        Map<String, Car> carMap = carMapper.selectBatchIds(carInfos.stream().map(CarInfo::getParentId).distinct().collect(Collectors.toList()))
                .stream()
                .collect(Collectors.toMap(Car::getCarId, Function.identity()));
        String info = carInfos.stream()
                .map(carInfo -> {
                    Car car = carMap.get(carInfo.getParentId());
                    return String.format("汽车品牌：%s-汽车名:%s-汽车颜色:%s-汽车版本:%s",car.getCarBrand(),car.getCarName(),carInfo.getInfoColor(),carInfo.getInfoVersion());
                }).collect(Collectors.joining("、"));
        //将采购订单内的零配件信息查出，并用顿号拼接零配件名
        String parts = sparePartsMapper.selectList(new QueryWrapper<SpareParts>().in("spare_parts_id", collect))
                .stream().map(SpareParts::getSparePartsName).collect(Collectors.joining("、"));
        String repoName = repositoryMapper.selectById(orderGroup.getPuroRepoId()).getRepoName();
        //最后拼接订单组名当前用户的userName创建的xxx汽车||xxx零配件
        return loginUser.getUsername()+"创建:"+info+" && "+parts+"仓库："+repoName;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeAllById(String id,LoginUser cur) {
        try {
            orderGroupMapper.updateById(new OrderGroup().setId(id).setDeleted(DeletedEnum.TRUE));
            Optional.ofNullable(purchaseOrderMapper.selectList(new QueryWrapper<PurchaseOrder>().eq("order_group_id",id))).ifPresent(
                    purchaseOrders -> purchaseOrders.forEach(purchaseOrder -> {
                        purchaseOrder.setUpdatedTime(new Date());
                        purchaseOrder.setUpdatedBy(cur.getUsername());
                        purchaseOrder.setDeleted(DeletedEnum.TRUE);
                        purchaseOrder.setPuroStatus(2);
                        purchaseOrderMapper.updateById(purchaseOrder);
                    }));
            return 0;
        }catch (Exception e){
            return -1;
        }
    }

    @Override
    public List<PuroQueryByIdVo> getPuroById(String id) {
        try {
            List<PurchaseOrder> orderList = purchaseOrderMapper.selectList(new QueryWrapper<PurchaseOrder>().eq("order_group_id", id).eq("deleted",DeletedEnum.FALSE));
            return orderList.stream().map(order -> {
                PuroQueryByIdVo vo = PuroQueryByIdVo.makeVo(order);
                AtomicBoolean flag = new AtomicBoolean(false);
                //名字
                Optional.ofNullable(carInfoMapper.selectById(vo.getPuroGoodsId())).ifPresent(carInfo -> {
                    vo.setPuroGoodsName(carInfo.getInfoManufacturer()+carInfo.getInfoVersion()+carInfo.getInfoColor());
                    flag.set(true);
                });
                if (!flag.get()){
                    vo.setPuroGoodsName(sparePartsMapper.selectById(vo.getPuroGoodsId()).getSparePartsName());
                }
                //供应商
               Optional.ofNullable(supplierMapper.selectById(vo.getPuroPurId())).ifPresent(pur->{
                   vo.setPuroPurName(pur.getPurName());
               });
                //仓库
               Optional.ofNullable(repositoryMapper.selectById(vo.getPuroRepoId())).ifPresent(repository->{
                   vo.setPuroRepoName(repository.getRepoName());
               });

                return vo;
            }).collect(Collectors.toList());
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int includeStock(String id,LoginUser loginUser) {
        try {
            //查到这个订单的基本信息
            OrderGroup orderGroup = orderGroupMapper.selectById(id);
            List<PurchaseOrder> orderList = purchaseOrderMapper.selectList(new QueryWrapper<PurchaseOrder>().eq("order_group_id", id));
            if (orderList.get(0).getPuroStatus() != 0){
                return -1;
            }
            orderGroup.setPurchaseOrderList(orderList);
            //先找一下库存里有没有这个订单的商品，没有就创建记录，有就直接再基础上增加
            QueryWrapper<Stock> wrapper = new QueryWrapper<>();
            wrapper.eq("stock_repo_id",orderGroup.getPurchaseOrderList().get(0).getPuroRepoId());
            wrapper.in("stock_goods_id",orderGroup.getPurchaseOrderList().stream().map(PurchaseOrder::getPuroGoodsId).collect(Collectors.toList()));
            //循环添加库存记录或修改库存记录
            List<Stock> stocks = stockMapper.selectList(wrapper);

            Map<String, PurchaseOrder> maps = orderGroup.getPurchaseOrderList().stream().collect(Collectors.toMap(order -> order.getPuroGoodsId() + "," + order.getPuroRepoId(), Function.identity()));

            //给已经有记录的添加库存
            stocks.forEach(stock -> {
                if (maps.containsKey(stock.getId())){
                    PurchaseOrder purchaseOrder = maps.get(stock.getId());
                    Integer afterCount = stock.getStockCount();
                    Integer addCount = purchaseOrder.getPuroCount();
                    stock.setStockCount(afterCount+addCount);
                    stock.setUpdatedTime(new Date());
                    stock.setUpdatedBy(loginUser.getUsername());
                    stockMapper.updateById(stock);
                    maps.remove(stock.getId());
                    //更新一下入库时间
                    purchaseOrder.setPuroImportTime(new Date());
                    purchaseOrder.setPuroInspectUserId(loginUser.getId());
                    purchaseOrder.setPuroStatus(1);
                    purchaseOrderMapper.updateById(purchaseOrder);
                }
            });
            //给没有记录的新增记录
            maps.forEach((key, order) -> {
                stockMapper.insert(new Stock()
                        .setStockCount(order.getPuroCount())
                        .setId(order.getPuroGoodsId()+","+order.getPuroRepoId())
                        .setCreatedBy(loginUser.getUsername())
                        .setCreatedTime(new Date())
                        .setStockGoodsId(order.getPuroGoodsId())
                        .setStockRepoId(order.getPuroRepoId())
                );
                //入库时设置该订单的审核人,并更新订单状态
                order.setPuroInspectUserId(loginUser.getId());
                order.setPuroStatus(1);
                order.setPuroImportTime(new Date());
                purchaseOrderMapper.updateById(order);
            });
            return 0;
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String removeOrderById(String id,LoginUser cur) {
        String message = purchaseOrderMapper.updateById(new PurchaseOrder().setId(id).setDeleted(DeletedEnum.TRUE).setPuroStatus(2).setUpdatedBy(cur.getUsername()).setUpdatedTime(new Date())) == 1 ? "删除成功" : "删除失败";
        Integer count = purchaseOrderMapper.selectCount(new QueryWrapper<PurchaseOrder>().eq("order_group_id", id).eq("deleted", DeletedEnum.FALSE));
        if (count == 0){
            orderGroupMapper.updateById(new OrderGroup().setId(id).setDeleted(DeletedEnum.TRUE));
        }
        return message;
    }
}
